// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import { AudioManager } from "./GameCore";
import Planet from "./Planet";

const {ccclass, property} = cc._decorator;

@ccclass
export default class SunCraft extends cc.Component {

    @property({
        type: cc.AudioClip,
        tooltip: '背景音乐'
    })
    bgm: cc.AudioClip = null

    @property({
        type: cc.Prefab,
        tooltip: '行星预制'
    })
    planetPrefab: cc.Prefab = null
  
    planets = []
    isCreating = false
    currentPlanet = null
    planetCount = 0
    line: cc.Node = null
    systemNode: cc.Node = null
    defeat = false

    onLoad () {
        this.initPhysics()
        this.line = this.node.getChildByName('line')
        this.systemNode = this.node.getChildByName('planets')
        // 加载并设置音乐分包 
        cc.assetManager.loadBundle('audio', (err, bundle) => {
            if (err) {
                cc.log('Error url [' + err + ']');
                return;
            }
            AudioManager.setBundle(bundle)
            if (this.bgm) AudioManager.playBgm(this.bgm, 1);
            // 初始化关卡内容

            this.isCreating = false
            this.planetCount = 0

            // 监听点击事件 todo 是否能够注册全局事件
            this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this)
            this.node.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMove, this)
            this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this)
            this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this)

            this.initOnePlanet()
        });
    }

    // 开启物理引擎和碰撞检测
    initPhysics () {
        // 物理引擎
        const instance = cc.director.getPhysicsManager()
        instance.enabled = true
        instance.gravity = cc.v2(0, -960);

        // 碰撞检测
        const collisionManager = cc.director.getCollisionManager();
        collisionManager.enabled = true

        // 设置四周的碰撞区域
        let width = this.node.width;
        let height = this.node.height;

        let node = new cc.Node();

        let body = node.addComponent(cc.RigidBody);
        body.type = cc.RigidBodyType.Static;

        const _addBound = (node, x, y, width, height) => {
            let collider = node.addComponent(cc.PhysicsBoxCollider);
            collider.offset.x = x;
            collider.offset.y = y;
            collider.size.width = width;
            collider.size.height = height;
        }

        _addBound(node, 0, -height / 2, width, 1);
        _addBound(node, 0, height / 2, width, 1);
        _addBound(node, -width / 2, 0, 1, height);
        _addBound(node, width / 2, 0, 1, height);

        node.parent = this.node;

    }

    initOnePlanet (index = 0) {
        if (this.defeat) return
        this.planetCount++
        let y = this.node.getChildByName('line').y + 80
        let planet = cc.instantiate(this.planetPrefab);

        planet.getComponent(Planet).init(index, this);
        planet.getComponent(cc.RigidBody).type = cc.RigidBodyType.Static
        planet.getComponent(cc.PhysicsCircleCollider).radius = 0

        this.systemNode.addChild(planet);
        planet.scale = 0.6

        planet.setPosition(cc.v2(0, y));
        this.currentPlanet = planet
    }

    /**
     * 开始触摸屏幕
     * @param event 触摸事件
     */

    onTouchStart (event) {
        if (this.isCreating) return
        this.isCreating = event.touch
        this.onTouchMove(event)
    }
    
    /**
     * 屏幕上触点滑动
     * @param event 触摸事件
     */
    
    onTouchMove (event) {
        if (this.isCreating != event.touch || this.defeat) return
        let x = this.node.convertToNodeSpaceAR(event.getLocation()).x
        this.currentPlanet.x = Math.sign(x) * Math.min(Math.abs(x), this.node.width / 2 - this.currentPlanet.width * this.currentPlanet.scale / 2 - 1)
    }
    
    /**
     * 松开屏幕
     * @param event 触摸事件
     */
    
    onTouchEnd (event) {
        if (this.isCreating != event.touch || this.defeat) return
        this.currentPlanet.getComponent(Planet).startPhysics()
        // 设置一秒后生成新行星
        cc.tween(this.node)
        .delay(1)
        .call(() => {
            const nextId = this.getNextPlanetId()
            this.initOnePlanet(nextId)
            this.isCreating = false
        })
        .start()
    }

    // 获取下一个行星的种类

    getNextPlanetId () {
        if (this.planetCount < 3) {
            return 0
        } else if (this.planetCount === 3) {
            return 1
        } else {
            // 随机返回前5个
            return Math.floor(Math.random() * 5)
        }
    }

    gameOver () {
        if (this.defeat) return
        this.defeat = true
        cc.director.getPhysicsManager().enabled = false
        this.systemNode.children.forEach((planet, index) => {
            cc.tween(planet)
            .delay(index * 0.2)
            .call((node) => {
                let planet = node.getComponent(Planet)
                planet.createCraft()
                AudioManager.playSe(planet.sounds[2], 1)
            })
            .to(0.5, {scale: 0})
            .start()
        });
        cc.tween(this.node)
        .delay(this.systemNode.children.length * 0.2 + 2)
        .call(() => {
            cc.director.loadScene('game')
        })
        .start()
    }
}
